Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add float conversions to and from bytes #62366

Merged
merged 2 commits into from
Jul 8, 2019

Conversation

tesuji
Copy link
Contributor

@tesuji tesuji commented Jul 4, 2019

Rework of #58756. Address #58756 (comment).

Fixes #57492.

r? @SimonSapin

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 4, 2019
@tesuji
Copy link
Contributor Author

tesuji commented Jul 4, 2019

Is this intended?

info: removing rustup home
error: could not remove 'rustup_home' directory: '/usr/local/rustup'
info: caused by: Permission denied (os error 13)
Attempting to download https://.s3.amazonaws.com/docker/2f511ff28d2c3389996e6646724384337055dbe17514450f68a74b45672fa86ebd4e2373065cd78cea881bbf1f9ccb272982a872df86a3476451bf3eaec60ea7
Attempting with retry: curl -y 30 -Y 10 --connect-timeout 30 -f -L -C - -o /tmp/rustci_docker_cache https://.s3.amazonaws.com/docker/2f511ff28d2c3389996e6646724384337055dbe17514450f68a74b45672fa86ebd4e2373065cd78cea881bbf1f9ccb272982a872df86a3476451bf3eaec60ea7
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: .s3.amazonaws.com
Command failed. Attempt 2/5:
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: .s3.amazonaws.com
Command failed. Attempt 3/5:
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: .s3.amazonaws.com
Command failed. Attempt 4/5:
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: .s3.amazonaws.com
Command failed. Attempt 5/5:
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: .s3.amazonaws.com
The command has failed after 5 attempts.
open /tmp/rustci_docker_cache: no such file or directory

@tesuji
Copy link
Contributor Author

tesuji commented Jul 4, 2019

Hm, the build failed. It seems I cannot mark those methods as const method.
I also need to_bits, from_bits to be const.

What should I do, @Centril?

@Centril
Copy link
Contributor

Centril commented Jul 4, 2019

What should I do, @Centril?

Not mark them as const =)

(or alternatively do what I suggested in #58756 (comment) but it is better not to...)

@tesuji
Copy link
Contributor Author

tesuji commented Jul 4, 2019

r? @SimonSapin (It seems that scottmcm is busy)

@rust-highfive rust-highfive assigned SimonSapin and unassigned scottmcm Jul 4, 2019
@tbu-
Copy link
Contributor

tbu- commented Jul 5, 2019

Thanks for picking this up!

/// #![feature(float_to_from_bytes)]
/// let value = f32::from_be_bytes([0x40, 0x49, 0x0f, 0x67]);
/// let difference = (value - 3.141565f32).abs();
/// assert!(difference <= 1e-5);
Copy link
Contributor

@SimonSapin SimonSapin Jul 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not assert_eq!(value, 3.141565f32)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I think that floating point equality comparison is incorrect and
discourage.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I think that floating point equality comparison is incorrect and
discourage.

Normally this is true, but if you just created the float using a bit pattern, it must be actually equal to the expected value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will let the decision to Simon.

Copy link
Contributor

@SimonSapin SimonSapin Jul 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Floating point equality can give unexpected results (compared to the same operation on real numbers) when it’s done on the result of non-trivial computation, because precision errors can acumulate. For example 0.3+0.3+0.3 != 0.9.

But as @tbu- said, the conversions here should be exact. Please change to from_*_bytes and from_bits doctests to use assert_eq!, and let’s see if the tests pass.

Also, please imitate from_bits / to_bits in picking a floating point value like 12.5 that has a “nice” representation, and using hex literals for integers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I has a concern: What if people follow our style in their tests for
floating point equality?

Copy link
Contributor

@gnzlbg gnzlbg Jul 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally this is true, but if you just created the float using a bit pattern, it must be actually equal to the expected value.

Do we guarantee this for NaNs ? cc @rkruppe (As in, if one bitcasts a NaN bitpattern to a float, does LLVM guarantee that the bitpattern is preserved, or only that this float will be "some" NaN ?).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I highly doubt we have anything relevant explicitly written down. I don't know whether LLVM explicitly guarantees it for bitcasts only. I don't see why it wouldn't, but who knows. But even if LLVM explicitly stated that, that wouldn't mean we'd translate that into any Rust level guarantee.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, this PR does not introduce this problem. This is a problem that f32::from_bits and f64::from_bits already have, and these are stable, so I don't think clarifying this should hold this PR back. If we document this for those methods, that would just follow for these as well.

@mark-i-m
Copy link
Member

mark-i-m commented Jul 6, 2019

cc @gnzlbg, who I think worked a bit on the equivalent for integers? May be good to make sure we have consistent APIs...

Copy link
Contributor

@gnzlbg gnzlbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue where this was raised had very little attention (cc @nagisa), so I would be more comfortable if the @rust-lang/libs team would at least comment on their overall feeling of adding these convenience methods, so that we don't add something here that then remains unstable forever (EDIT: seems that this concern was raised in #58756, and that the general feeling was that its ok to land these and stabilize them at some point).

I first wrote "I have never needed this", but actually I have! Well not precisely these, but their SIMD vector type equivalent (e.g. here (*)). AFAICT adding these isn't strictly necessary, since one can combine the existing methods to achieve the same effect, but I personally don't mind having them, and it is the kind of small utility that, if it isn't part of standard, it probably won't be worth pulling in an external crate for. So this change feels harmless to me, and if it helps some users, then that's great.

EDIT: These methods have the same API as the from/to_le/be/ne_bytes methods for integers, so that's consistent. We do guarantee that f32 and f64 are always 4 and 8 bytes wide, so this API should always be correctly implementable for all platforms that we support.

(*) that code came from std::simd, so it predates the from/to_..._bytes methods, and it has at best unspecified behavior today, because the union isn't repr(C), but union wasn't even stable back then.

@SimonSapin
Copy link
Contributor

@lzutao You have a couple commits with “WIP” in the message. Do you mean to make further changes?

@tesuji
Copy link
Contributor Author

tesuji commented Jul 8, 2019

No, I don't. Those WIP commits will be rebased after the review process completed.

@SimonSapin
Copy link
Contributor

Ah ok. Here I was waiting for the changes to be completed, to finish reviewing :]

Anyway, the diff looks good now. r=me after you squash commits as desired.

@tesuji tesuji force-pushed the feature/float-from-to-bytes branch from d3f69bb to b15e4aa Compare July 8, 2019 07:33
@tesuji tesuji force-pushed the feature/float-from-to-bytes branch from b15e4aa to df53a3f Compare July 8, 2019 07:34
@SimonSapin
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Jul 8, 2019

📌 Commit df53a3f has been approved by SimonSapin

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 8, 2019
@bors
Copy link
Contributor

bors commented Jul 8, 2019

⌛ Testing commit df53a3f with merge 10840b8...

bors added a commit that referenced this pull request Jul 8, 2019
Add float conversions to and from bytes

Rework of #58756. Address #58756 (comment).

Fixes #57492.

r? @SimonSapin
@bors
Copy link
Contributor

bors commented Jul 8, 2019

☀️ Test successful - checks-azure, checks-travis, status-appveyor
Approved by: SimonSapin
Pushing 10840b8 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jul 8, 2019
@bors bors merged commit df53a3f into rust-lang:master Jul 8, 2019
@tesuji tesuji deleted the feature/float-from-to-bytes branch July 8, 2019 12:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

from_*e_bytes and to_n*_bytes equivalents for floats
10 participants